import moment from 'moment'

//  比较两个对象是否相等
export function equalObj(objA, objB) {
  if (typeof objB === 'object') {
    if (typeof objA !== 'object') return false
    for (const key of Object.keys(objA)) {
      if (!equalObj(objA[key], objB[key])) {
        return false
      }
    }
    return true
  } else if (objA instanceof Array && objB instanceof Array) {
    return equalArray(objA, objB)
  } else {
    return objA === objB
  }
}

//  比较两个数组是否相等
export function equalArray(arrayA, arrayB) {
  if (!arrayA || !arrayB) { return false }
  // 第一步最简单的长度
  if (arrayA.length !== arrayB.length) { return false }
  for (let i = 0, l = arrayA.length; i < l; i++) {
    // 检查是否嵌套
    if (arrayA[i] instanceof Array && arrayB[i] instanceof Array) {
      // 继续去递归调用
      if (!equalArray(arrayA[i], arrayB[i])) {
        return false
      }
    } else if (arrayA[i] instanceof Object && arrayB[i] instanceof Object) { // 如果数组元素是对象则调用equalObj()
      if (!equalObj(arrayA[i], arrayB[i])) {
        return false
      }
    } else if (arrayA[i] !== arrayB[i]) {
      return false
    }
  }
  return true
}

export function equalObjForUpdate(objA, objB) {
  const result = []
  for (const key of Object.keys(objA)) {
    if (objA[key] !== objB[key]) {
      result.push(key)
    }
  }
  return result
}

// 按数组元素对象的指定属性值排序
export function sortByProp(propertyName, type) {
  return function(obj1, obj2) {
    const v1 = obj1[propertyName]
    const v2 = obj2[propertyName]
    if (type === 'ascending') { // 升序
      return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0)
    } else { // 降序
      return v1 < v2 ? 1 : (v1 > v2 ? -1 : 0)
    }
  }
}

/**
 * 主表更新用
 * @param {*} original
 * @param {*} current
 * @param {*} mainKey 主表Id名称
 * @param {*} skipKeys 忽略的属性
 */
export function compareFormData(original, current, mainKey, skipKeys) {
  const result = {}
  skipKeys = skipKeys || []
  result[mainKey] = current[mainKey]
  for (const p of Array.from(new Set([...Object.keys(original), ...Object.keys(current)]))) {
    if (p === mainKey || skipKeys.includes(p)) {
      continue
    }
    if (original[p] !== current[p]) {
      result[p] = current[p]
    }
  }
  return result
}

/**
 * 从表更新用
 * @param {*} original
 * @param {*} current
 * @param {*} key 从表Id名称
 * @param {*} mainKey 主表Id名称
 * @param {*} skipKeys 忽略的属性
 * @param {*} userId 当前登录人Id
 */
export function compareList(original, current, key, mainKey, skipKeys, userId, idKey) {
  const result = {
    changed: false,
    deletes: [],
    adds: [],
    updates: []
  }
  // 主表Id
  const fId = original[0] ? original[0][mainKey] : idKey
  const currents = [] // 可能更新的项
  const current_ids = current.map(item => {
    if (!item[key]) {
      item[mainKey] = fId
      item.createUser = userId
      result.adds.push(item) // 新增的
    } else {
      currents.push(item)
      return item[key]
    }
  })
  const originals = [] // 可能更新的项对应的原始项
  original.forEach(item => {
    if (!current_ids.includes(item[key])) {
      result.deletes.push(item[key]) // 删除的
    } else {
      originals.push(item)
    }
  })
  for (let i = 0, j = currents.length; i < j; i++) {
    const result_ = compareFormData(originals[i], currents[i], key, skipKeys)
    if (Object.keys(result_).length > 1) {
      result.updates.push(result_)
    }
  }
  if (result.deletes.length || result.adds.length || result.updates.length) {
    result.changed = true
  }
  return result
}

/**
 *
 * @param {*} original  主表元数据
 * @param {*} current   主表编辑后的数据
 * @param {*} originalList  从表元数据
 * @param {*} currentList   从表编辑后的数据
 * @param {*} mainKey 主表Id名称
 * @param {*} key 从表Id名称
 * @param {*} skipKeys1,skipKeys2 忽略的属性
 * @param {*} userId 当前登录人Id
 */
export function compareForUpdate(original, current, originalList, currentList, mainKey, key, skipKeys1, skipKeys2, userId, idKey) {
  const o1 = compareFormData(original, current, mainKey, skipKeys1)
  if (Object.keys(o1).length > 1) {
    o1.mainChanged = true
  } else {
    o1.mainChanged = false
  }
  const o2 = compareList(originalList, currentList, key, mainKey, skipKeys2, userId, idKey)
  Object.assign(o1, o2)
  if (!o1.mainChanged) {
    delete o1[mainKey]
  }
  if (o1.changed) {
    o1.deletes = o1.deletes.length ? o1.deletes.join(',') : undefined
    o1.adds = o1.adds.length ? JSON.stringify(o1.adds) : undefined
    o1.updates = o1.updates.length ? JSON.stringify(o1.updates) : undefined
  } else {
    delete o1.deletes
    delete o1.adds
    delete o1.updates
  }
  return o1
}

/**
 * @Author WANG SHENG
 * @Description 获取两个日期之间的每一天
 * @Date 16:23 2021/4/14
 **/
export function getDateInterval(begin, end) {
  const res = []
  var ab = begin.split('-')
  var ae = end.split('-')
  var db = new Date()
  db.setUTCFullYear(ab[0], ab[1] - 1, ab[2])
  var de = new Date()
  de.setUTCFullYear(ae[0], ae[1] - 1, ae[2])
  var unixDb = db.getTime()
  var unixDe = de.getTime()
  for (var k = unixDb; k <= unixDe;) {
    res.push(moment(new Date(k)).format('YYYY-MM-DD'))
    k = k + 24 * 60 * 60 * 1000
  }
  return res
}
/**
 * 构造树型结构数据
 * @param {*} data 数据源
 * @param {*} id id字段 默认 'id'
 * @param {*} parentId 父节点字段 默认 'parentId'
 * @param {*} children 孩子节点字段 默认 'children'
 */
export function handleTree(data, id, parentId, children) {
  const config = {
    id: id || 'id',
    parentId: parentId || 'parentId',
    childrenList: children || 'children'
  }

  var childrenListMap = {}
  var nodeIds = {}
  var tree = []

  for (const d of data) {
    const parentId = d[config.parentId]
    if (childrenListMap[parentId] == null) {
      childrenListMap[parentId] = []
    }
    nodeIds[d[config.id]] = d
    childrenListMap[parentId].push(d)
  }

  for (const d of data) {
    const parentId = d[config.parentId]
    if (nodeIds[parentId] == null) {
      tree.push(d)
    }
  }

  for (const t of tree) {
    adaptToChildrenList(t)
  }

  function adaptToChildrenList(o) {
    if (childrenListMap[o[config.id]] !== null) {
      o[config.childrenList] = childrenListMap[o[config.id]]
    }
    if (o[config.childrenList]) {
      for (const c of o[config.childrenList]) {
        adaptToChildrenList(c)
      }
    }
  }
  return tree
}

// / <summary>
// / 格式化文件大小的JS方法
// / </summary>
// / <param name="filesize">文件的大小,传入的是一个bytes为单位的参数</param>
// / <returns>格式化后的值</returns>
export function getFileSize(filesize) {
  if (filesize == null || filesize === '') {
    return '0 Bytes'
  }
  var unitArr = new Array('Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB')
  var index = 0
  var srcsize = parseFloat(filesize)
  index = Math.floor(Math.log(srcsize) / Math.log(1024))
  var size = srcsize / Math.pow(1024, index)
  size = size.toFixed(2)// 保留的小数位数
  return size + unitArr[index]
}

